/*****************************************************
 * 検索結果一覧テーブルの描画を行うクラスの基底クラス
 * @abstract
 * @author kino
 *****************************************************/
/**
 * コンストラクタ
 * @param {AbstractResults} data このビューが表示するデータ。非null。
 */
function AbstractResultsView(session, query, data){
    /** {Session} サーバとの接続セッション情報 */
    this.session = session;
    
    /** {Query}　このビューが表示するクエリ */
    this.query = query;
    
    /** {AbstractResults} このビューが表示する一覧データ */
    this.data = data;
}

/**
 * id=result-bodyで指定されるHTML要素が存在するとして、そこに結果表示ビューを構築する。
 * 該当要素に元から入っていた要素はすべて破棄する。
 */
AbstractResultsView.prototype.constructView = function(){
    $('#result-body').empty();
    $('#result-body').append(this.createView());
    this.setEvent();
}

/**
 * 設定されている条件・保持している検索結果にあわせ、結果表示ビューのHTMLを構築する。
 */
AbstractResultsView.prototype.createView = function(){
    var result = '';
    result += '<div id="view-body">';
    result += '<div id="month-select-area">';
    result += this.createMonthSelector();
    result += '</div>'
    result += '<div id="result-table-area">'
    result += this.createTable();
    result += '</div>';
    result += '<div id="input-form-area">'
    result += this.createInputForm();
    result += '</div>';
    result += '</div>';
    return result;
}

/**
 * 保持しているクエリにあわせ、月選択エリアを構築する。
 * @return {String} 月選択エリアのHTML文字列。
 */
AbstractResultsView.prototype.createMonthSelector = function(){
    var result = '';
    result += '<span class="month-handle" id="previous-month-handle"><img src="../img/previous-month-handle.png"></span>';
    result += '<span id="current-month">' + this.query.year + '/' + this.query.month + '</span>';
    result += '<span class="month-handle" id="next-month-handle"><img src="../img/next-month-handle.png"></span>';
    return result;
}

/**
 * 保持している一覧データから、一覧のテーブル表現を構築する。
 * @abstract
 * @return {String} 一覧HTML文字列。<table>～</table>
 */
AbstractResultsView.prototype.createTable = function(){
    throw new Error("This method is abstract.");
}

/**
 * 表示するデータタイプにあった、新規データ入力欄を構築する。
 * @abstract
 * @return {String} 入力フォームのHTML文字列。
 */
AbstractResultsView.prototype.createInputForm = function(){
    throw new Error("This method is abstract.");
}

/**
 * ビューに対する各種イベントを設定する。
 */
AbstractResultsView.prototype.setEvent = function(){
    this.setMonthSelectorEvent();
    this.setResultTableEvent();
    this.setInputFormEvent();
}

/**
 * 月選択エリアに対するマウスイベントを設定する。
 */
AbstractResultsView.prototype.setMonthSelectorEvent = function(){
    var self = this;
    $('#previous-month-handle').click(function(){
        self.requestPreviousMonth();
    });
    
    $('#next-month-handle').click(function(){
        self.requestNextMonth();
    });
    
    $('span.month-handle').hover(function(){
        $(this).css('cursor', 'pointer');
    }, function(){
        $(this).css('cursor', 'auto');
    });
}

/**
 * 前月のデータの検索を要求する
 */
AbstractResultsView.prototype.requestPreviousMonth = function(){
    this.query.month--;
    if (this.query.month <= 0) {
        this.query.month = 12;
        this.query.year--;
    }
    this.search();
}

/**
 * 次月のデータの検索を要求する
 */
AbstractResultsView.prototype.requestNextMonth = function(){
    this.query.month++;
    if (this.query.month >= 13) {
        this.query.month = 1;
        this.query.year++;
    }
    this.search();
}

/**
 * 結果一覧エリアに対する各種イベントを設定する。
 * @abstract
 */
AbstractResultsView.prototype.setResultTableEvent = function(){
    throw new Error("This method is abstract.");
}

/**
 * 新規データ入力フォームに対する各種イベントを設定する。
 * @abstract
 */
AbstractResultsView.prototype.setInputFormEvent = function(){
    throw new Error("This method is abstract.");
}

/**
 * 検索を実行するロジック本体。
 */
AbstractResultsView.prototype.search = function(){
    var query = this.createQuery();
    SearchLogic.search(this, query);
}

/**
 * 保持しているセッション情報・クエリ情報から、サーバに投げるPOSTクエリを構築する
 * @abstract
 * @return {Map} POSTクエリデータ。
 */
AbstractResultsView.prototype.createQuery = function(){
    throw new Error("This method is abstract.");
}

/**
 * 検索結果を処理するコールバックメソッド。
 * @param {JSON} response 検索結果として帰ってきたデータ。JSON形式をevalしたもの。
 */
AbstractResultsView.prototype.searchCallback = function(response){
	// TODO response.error の存在チェック。あれば検索がエラーだったとして処理
	var result = response.result;
    this.data.fromJson(result);
    this.constructView();
}
